# -*- coding: utf-8 -*-

import unittest

from hurryoff.core.router import Router
from hurryoff.core.filters import transferFilter
import hurryoff.core.router as router
from hurryoff.db import *
from hurryoff.db.base import Base

import os
from sqlalchemy import create_engine
from datetime import time

class RouterTests(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        if os.path.dirname(__file__) not in ('', None):
            os.chdir(os.path.dirname(__file__))
        cls.setupDB()

    def test_getRoute(self):
        self.assertEqual(len(self.getRoutes(u"київ-пас.", u"вінниця")), 1)
        self.assertEqual(len(self.getRoutes(u"київ-пас.", u"москва київська")), 4)
        self.assertEqual(len(self.getRoutes(u"київ-пас.", u"москва київська", filters=[transferFilter])), 3)

    def getRoutes(self, fromLocation, toLocation, filters=None):
        routes = []
        router = Router(fromLocation, toLocation, filters=filters)
        for route in router.getRoutes():
            present = len([r for r in routes if self.listEquals(route, r)]) > 0
            if not present:
                routes.append(route)
                self.printRoute(route)
        return routes

    def listEquals(self, list1, list2):
        if (list1 is None) or (list2 is None):
            return False
        if len(list1) != len(list2):
            return False
        return len([part for part in list1 if part in list2]) == len(list1)

    def printRoute(self, route):
        print("------------------------------------")
        for part in route:
            print("'%s' ('%s') => '%s' ('%s') : '%d'" % (part.startPoint.encode('utf-8'), part.departureTime, part.destinationPoint.encode('utf-8'), part.destinationTime, part.trainId))

    def test_isDirectlyConnected(self):
        isDirectlyConnected, trains = router.isDirectlyConnected(u"київ-пас.", u"вінниця")
        self.assertTrue(isDirectlyConnected)
        self.assertTrue(len(trains) > 0)
        self.assertFalse(router.isDirectlyConnected(u"суземка", u"вінниця")[0])

    def test_getNeighboring(self):
        neighbors = router.getNeighboring(u"київ-пас.")
        stations = []
        for (train_id, station) in neighbors.items():
            stations.append(station.name)
        self.assertTrue(len(stations) == 3)
        self.assertTrue(u"козятин-1" in stations)
        self.assertTrue(u"хутір михайлівський" in stations)
        self.assertTrue(u"конотоп-пас." in stations)

    def test_getPathPart(self):
        partPath = router.getPathPart(u"київ-пас.", u"вінниця", 4)
        self.assertEqual(partPath.startPoint, u"київ-пас.")
        self.assertEqual(partPath.destinationPoint, u"вінниця")
        self.assertEqual(partPath.departureTime, time(23, 14))
        self.assertEqual(partPath.destinationTime, time(2, 16))
        self.assertEqual(partPath.trainId, 4)

    @classmethod
    def setupDB(cls):
        engine = create_engine("mysql://test:testpswd@localhost/test_hurryoff?charset=utf8", echo=False)
        DBSession.configure(bind=engine)
        Base.metadata.bind = engine
        Base.metadata.drop_all(Base.metadata.bind)
        engine.execute(open('testData.sql', 'r').read())
